package com.sky.aop;

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * @Author: 放学后海堤日记
 * @Date: 2023/4/27 16:05
 * @Desc: 拦截数据库insert、update操作，对公共字段进行填充
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    @Before("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取数据库操作类型
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);
        OperationType type = annotation.value();
        log.info("数据库操作类型是：{}", type);

        Object category = joinPoint.getArgs()[0];
        Class<?> aClass = category.getClass();

        if (type.equals(OperationType.INSERT)) {
            Method setCreateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            Method setCreateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
            Method setUpdateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method setUpdateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

            setCreateUser.invoke(category, BaseContext.getCurrentId());
            setUpdateUser.invoke(category, BaseContext.getCurrentId());
            setUpdateTime.invoke(category, LocalDateTime.now());
            setCreateTime.invoke(category, LocalDateTime.now());

        } else if (type.equals(OperationType.UPDATE)) {
            Method setUpdateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method setUpdateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

            setUpdateUser.invoke(category, BaseContext.getCurrentId());
            setUpdateTime.invoke(category, LocalDateTime.now());
        }
    }
}
